<?php
use \Roboframe\ActiveRecord\Model;
class User extends Model {
  static $default_includes = array('user_roles' => array('role'));
  
  static $validates_length_of = array(
    array('login',    'within' => array(3, 40))
   ,array('password', 'within' => array(5, 40))
  );

  static $validates_presence_of = array(
    array('login')
   ,array('email')
   ,array('password')
   ,array('password_confirmation')
   ,array('salt')
  );
  
  static $validates_uniqueness_of = array(
    array('login')
   ,array('email')
  );
  
  static $validates_format_of = array(
    array('email', 'with' => '/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i', 'message' => 'Invalid email')
  );
  // RBAC
  static $has_many = array(
    array('user_roles')
   ,array('roles', 'through' => 'user_roles') 
  );
  
  // RBAC
  public function permissions() {
    $roles = $this->roles;
    $permissions = array();
    foreach($roles as $role) {
      $permissions = array_merge($permissions, $role->permissions);
    }
    return $permissions;
  }


  //validates_confirmation_of :password
  public function validate() {
    if ($this->password != $this->password_confirmation) {
      $this->errors->add('password', "Passwords are not the same");
    }
  }
  
  static $attr_protected = array('id', 'salt');
  
  //static $attr_accessor = array('password', 'password_confirmation');
  
  public static function random_string($length) {
    $new_password = '';
    for($i = 0; $i < $length; $i++) {
      $digit = rand(1,30)%2;
      $new_password.= $digit ? chr(rand(65,90)) : chr(rand(48,57)); 
    }
    return $new_password;
  }
  

  static $setters = array('password', 'password_confirmation');
  static $getters = array('password', 'password_confirmation');
  
  public function get_password() {
    return @$this->password;
  }
  
  public function get_password_confirmation() {
    return @$this->password_confirmation;
  }

  public function set_password($password) {
    $this->password = $password;
    if(!$this->salt) { 
      $this->salt = self::random_string(10); 
    }
    $this->hashed_password = self::encrypt($this->password, $this->salt);
  }
  
  public function set_password_confirmation($password_confirmation) {
    $this->password_confirmation = $password_confirmation;
  }
  
  public static function encrypt($password, $salt) {
    return sha1($password.$salt);
  }  
  
  public static function authenticate($login, $password) {
    $u = self::find('first', array('conditions' => array("login = ?", $login)));
    if(is_null($u)) {
      return null;
    }
    if(self::encrypt($password, $u->salt) == $u->hashed_password) {
      return $u;
    }
    return null;
  }
  
  public function send_new_password() {
    $new_pass = User::random_string(10);
    $this->password = $this->password_confirmation = $new_pass;
    $this->save();
    return NotificationMailer::deliver_forgot_password($this->email, $this->login, $new_pass);
  }
/*
def send_new_password
  new_pass = User.random_string(10)
  self.password = self.password_confirmation = new_pass
  self.save
  Notifications.deliver_forgot_password(self.email, self.login, new_pass)
end

*/ 
 
  /*
  public static function fields() {
    $columns = array();
    $t = new \ActiveRecord\Table(get_called_class());
    foreach($t->columns as $c) {
      $columns[] = $c->name;
    }
    return $columns;
  }
  
  static public function authenticate($username, $password) {
    return User::find_by_username_and_hashed_password($username, md5($password));
  }
  */
}